#ifndef __WED_DEV_H__
#define __WED_DEV_H__

#include <stdio.h>
#include <stdint.h>
#include "Wed_errno.h"
#include "Wed_common.h"
#include "Wed_list.h"
#include "kernel/Wed_mutex.h"

/* \brief 设备名长度 */
#define WED_DEV_NAME_LEN         32
/* \brief 无设备 */
#define WED_NO_DEV               0xFAFBFCFD

//#define WED_DEV_TYPE_CDEV        1    /* 字符设备 */
//#define WED_DEV_TYPE_BLK_DEV     2    /* 块设备 */

enum {
    WED_DEV_TYPE_UART   = 1,
    WED_DEV_TYPE_GPIO   = 2,
    WED_DEV_TYPE_PHY    = 3,
    WED_DEV_TYPE_NETDEV = 4,
};

/* \brief 设备操作函数集 */
struct Wed_dev_opts {
    int (*p_fn_init)(void *p_opts_arg);
    int (*p_fn_write)(void *p_opts_arg, uint8_t *p_data, uint32_t data_len);
};

/* \brief 基础设备结构体 */
struct Wed_dev {
    int                   type;                       /* 设备类型 */
    char                  name[WED_DEV_NAME_LEN];     /* 设备名 */
    struct Wed_dev_opts  *p_opts;                     /* 操作函数集 */
    void                 *p_opts_arg;                 /* 操作函数参数 */
    struct Wed_list_node  node;
};

/**
 * \brief 设备链表初始化
 *
 * @return 成功返回 0
 */
int Wed_dev_list_init(void);
/**
 * \brief 设备初始化并添加
 *
 * @param p_dev      设备结构体
 * @param p_dev_name 设备名
 * @param type       设备类型
 * @param p_opts     设备操作函数
 * @param p_usr_data 用户数据
 *
 * @return 成功返回 0
 */
int Wed_dev_init_add(struct Wed_dev      *p_dev,
                     char                *p_dev_name,
                     int                  type,
                     struct Wed_dev_opts *p_opts,
                     void                *p_opts_arg);
/**
 * \brief 通过设备名字寻找设备
 *
 * @param p_dev_name 设备名
 *
 * @return 找到返回设备结构体，没找到返回 NULL
 */
struct Wed_dev *Wed_dev_find_by_name(char *p_dev_name);
/**
 * \brief 设备写函数
 *
 * @param p_dev    设备结构体
 * @param p_data   要写的数据缓存
 * @param data_len 要写的数据长度
 *
 * @return 返回实际写的数据长度
 */
int Wed_dev_write(struct Wed_dev *p_dev, uint8_t *p_data, uint32_t data_len);
#endif
